package com.cssw.fyzb.core.eao.video;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.core.es.EsClient;
import com.cssw.fyzb.core.model.eos.VideoEo;
import com.cssw.fyzb.core.model.eos.VideoLikeEo;
import com.cssw.fyzb.core.util.DateUtil;
import com.ydn.dbframe.plugin.activerecord.Page;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author YangYiQun
 */
@Component
public class VideoLikeEaoImpl implements VideoLikeEao {

    @Autowired
    private EsClient esClient;

    private final static String INDEX_NAME = "fyzb_video_like";
    private final static String TYPE_NAME = "fyzb_video_like";

    @Override
    public void save(Long userId, Long videoId, Long videoUserId, String title, String media, String cover, Date likeTime) {
        VideoLikeEo videoLikeEo = new VideoLikeEo();
        videoLikeEo.setUserId(userId);
        videoLikeEo.setVideoId(videoId);
        videoLikeEo.setVideoUserId(videoUserId);
        videoLikeEo.setTitle(title);
        videoLikeEo.setMedia(media);
        videoLikeEo.setCover(cover);
        videoLikeEo.setLikeTime(DateUtil.format(likeTime));

        esClient.getClient()
                .prepareIndex(INDEX_NAME, TYPE_NAME)
                .setSource(JSON.parseObject(JSON.toJSONString(videoLikeEo)))
                .get()
        ;
    }

    @Override
    public long delete(Long userId, Long videoId) {
        VideoLikeEo videoLikeEo = new VideoLikeEo();
        videoLikeEo.setUserId(userId);
        videoLikeEo.setVideoId(videoId);

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter().add(QueryBuilders.termQuery("userId", userId));
        queryBuilder.filter().add(QueryBuilders.termQuery("videoId", videoId));

        BulkByScrollResponse response = DeleteByQueryAction.INSTANCE.newRequestBuilder(esClient.getClient())
                        .filter(queryBuilder)
                        .source(INDEX_NAME)
                        .get();

        return response.getDeleted();
    }

    @Override
    public Page<VideoLikeEo> pageByUserId(int pageNumber, int pageSize, Long userId) {
        pageNumber = pageNumber - 1;

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termQuery("userId", userId));

        SearchResponse response = esClient.getClient()
                .prepareSearch(INDEX_NAME)
                .setTypes(TYPE_NAME)
                .setQuery(queryBuilder)
                .setFrom(pageNumber * (pageSize - 1))
                .setSize(pageSize)
                .addSort(
                        SortBuilders.fieldSort("videoId").order(SortOrder.DESC)
                ).get();

        return toPage(response, pageNumber, pageSize);
    }


    private Page<VideoLikeEo> toPage(SearchResponse response, int pageNumber, int pageSize) {
        Page<VideoLikeEo> page = new Page<>();
        int count = (int) response.getHits().totalHits;
        page.setTotalPage((int) Math.ceil(count * 1.0 / pageSize));
        page.setTotalRow(count);
        page.setPageNumber(pageNumber);
        page.setPageSize(pageSize);
        List<VideoLikeEo> list = new ArrayList<>();
        for (SearchHit hit : response.getHits()) {
            list.add(JSON.parseObject(JSON.toJSONString(hit.getSourceAsMap()), VideoLikeEo.class));
        }
        page.setList(list);
        return page;
    }
}
